﻿/*
 * @Autor: PK
 * @Date: 2022/01/13 10:34:SS
 */

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace ShkSimulation.desktop.setting.model {

	public class ConverUtil {

		public static (IList<StationConfigModel>, IList<RoadConfigModel>, IList<DemandConfigModel>)
			DataTableToConfigModels(DataTable tempStation, DataTable tempRoad, DataTable tempDemand, out bool sucess) {
			try {
				List<StationConfigModel> station = ConvertToList<StationConfigModel>(tempStation);
				List<RoadConfigModel> road = ConvertToList<RoadConfigModel>(tempRoad);
				List<DemandConfigModel> demand = ConvertToList<DemandConfigModel>(tempDemand);
				sucess = true;
				return (station, road, demand);
			} catch (Exception e) {
				Console.WriteLine(e);
				sucess = false;
				return (null, null, null);
			}

		}
		
		public static DataRow EntityToDataRows<T>(DataTable table, T entity) where T: new() {
			List<DataRow> dataRows = EntityToDataRows(table, new List<T>(){entity});
			if (dataRows.Count == 0) {
				return null;
			}
			return dataRows.First();
		}
		
		public static List<DataRow> EntityToDataRows<T>(DataTable table, List<T> entities) where T: new() {
			var result = new List<DataRow>();
			if (entities == null || entities.Count == 0) {
				return result;
			}
			List<PropertyInfo> propertyInfos = typeof(T).GetProperties().ToList();
			Dictionary<int, PropertyInfo> valueMap = new Dictionary<int, PropertyInfo>();
			foreach (var propertyInfo in propertyInfos) {
				int index = table.Columns.IndexOf(propertyInfo.Name);
				if (index >= 0) {
					valueMap.Add(index, propertyInfo);
				}
			}
			foreach (var entity in entities) {
				DataRow row = table.NewRow();
				foreach (var (index, propertyInfo) in valueMap) {
					object value = propertyInfo.GetValue(entity, null);
					if (value != null) {
						row[index] = value;
						if (value == DBNull.Value) {
							row[index] = string.Empty;
						}
					}
				}
				result.Add(row);
			}
			return result;
		}

		public static List<T> ConvertToList<T>(DataTable table) where T: new() {
			var result = new List<T>();
			if (table.Rows.Count == 0) {
				return result;
			}
			result = ConvertToEntity<T>(table);
			return result;
		}

		public static List<T> ConvertToEntity<T>(DataTable table) where T: new() {
			var result = new List<T>();
			List<PropertyInfo> propertyInfos = typeof(T).GetProperties().Where(u => u.CanWrite).ToList();
			foreach (DataRow dataRow in table.Rows) {
				var entity = new T();
				foreach (PropertyInfo propertyInfo in propertyInfos) {
					string tmpName = propertyInfo.Name;
					if (!table.Columns.Contains(tmpName)) {
						continue;
					}
					
					object value = dataRow[tmpName];
					if (value != DBNull.Value) {
						propertyInfo.SetValue(entity, Convert.ChangeType(dataRow[tmpName], propertyInfo.PropertyType), null);
					}
				}
				result.Add(entity);
			}
			return result;
		}
	}

}